#pragma once
#ifndef __G_PRE_PROCESSOR_H__
#define __G_PRE_PROCESSOR_H__

#define G_PP_EMPTY	

// Description: Common definition for joining preprocessor definitions
// Notes:
// -----------------------------------------------------
#define G_PP_JOIN_DEF8(X, Y, Z, W, S, T, U, V)	G_PP_JOIN_DEF2(G_PP_JOIN_DEF7(X, Y, Z, W, S, T, U), V)
#define G_PP_JOIN_DEF7(X, Y, Z, W, S, T, U)		G_PP_JOIN_DEF2(G_PP_JOIN_DEF6(X, Y, Z, W, S, T), U)
#define G_PP_JOIN_DEF6(X, Y, Z, W, S, T)		G_PP_JOIN_DEF2(G_PP_JOIN_DEF5(X, Y, Z, w, S), T)
#define G_PP_JOIN_DEF5(X, Y, Z, W, S)			G_PP_JOIN_DEF2(G_PP_JOIN_DEF4(X, Y, Z, W), S)
#define G_PP_JOIN_DEF4(X, Y, Z, W)				G_PP_JOIN_DEF2(G_PP_JOIN_DEF3(X, Y, Z), W)
#define G_PP_JOIN_DEF3(X, Y, Z)					G_PP_JOIN_DEF2(G_PP_JOIN_DEF2(X, Y), Z)
#define G_PP_JOIN_DEF2(X, Y)					G_PP_JOIN_STR2(X, Y)

// Description: Common definition for joining preprocessor strings
// Notes:
// -----------------------------------------------------

#define G_PP_JOIN_STR8(X, Y, Z, W, S, T, U, V)	X##Y##Z##W##S##T##U##V
#define G_PP_JOIN_STR7(X, Y, Z, W, S, T, U)		X##Y##Z##W##S##T##U
#define G_PP_JOIN_STR6(X, Y, Z, W, S, T)		X##Y##Z##W##S##T
#define G_PP_JOIN_STR5(X, Y, Z, W, S)			X##Y##Z##W##S
#define G_PP_JOIN_STR4(X, Y, Z, W)				X##Y##Z##W
#define G_PP_JOIN_STR3(X, Y, Z)					X##Y##Z
#define G_PP_JOIN_STR2(X, Y)					X##Y

// Description: Definition for using a token as string
// Notes:
// -----------------------------------------------------
#define G_PP_STR(X)	#X


// Description: Definitions for value to binary conversion
// Notes:
// ----------------------------------------------------
#define G_PP_TO_BOOL(X)		G_PP_JOIN_DEF2(G_PP_TO_BOOL_, X)

#define G_PP_TO_BOOL_0		0
#define G_PP_TO_BOOL_1		1
#define G_PP_TO_BOOL_2		1
#define G_PP_TO_BOOL_3		1
#define G_PP_TO_BOOL_4		1
#define G_PP_TO_BOOL_5		1
#define G_PP_TO_BOOL_6		1
#define G_PP_TO_BOOL_7		1
#define G_PP_TO_BOOL_8		1
#define G_PP_TO_BOOL_9		1
#define G_PP_TO_BOOL_10		1
#define G_PP_TO_BOOL_11		1
#define G_PP_TO_BOOL_12		1
#define G_PP_TO_BOOL_13		1
#define G_PP_TO_BOOL_14		1
#define G_PP_TO_BOOL_15		1
#define G_PP_TO_BOOL_16		1
#define G_PP_TO_BOOL_17		1
#define G_PP_TO_BOOL_18		1
#define G_PP_TO_BOOL_19		1
#define G_PP_TO_BOOL_20		1
#define G_PP_TO_BOOL_21		1
#define G_PP_TO_BOOL_22		1
#define G_PP_TO_BOOL_23		1
#define G_PP_TO_BOOL_24		1
#define G_PP_TO_BOOL_25		1
#define G_PP_TO_BOOL_26		1
#define G_PP_TO_BOOL_27		1
#define G_PP_TO_BOOL_28		1
#define G_PP_TO_BOOL_29		1
#define G_PP_TO_BOOL_30		1
#define G_PP_TO_BOOL_31		1
#define G_PP_TO_BOOL_32		1
#define G_PP_TO_BOOL_33		1
#define G_PP_TO_BOOL_34		1
#define G_PP_TO_BOOL_35		1
#define G_PP_TO_BOOL_36		1
#define G_PP_TO_BOOL_37		1
#define G_PP_TO_BOOL_38		1
#define G_PP_TO_BOOL_39		1
#define G_PP_TO_BOOL_40		1
#define G_PP_TO_BOOL_41		1
#define G_PP_TO_BOOL_42		1
#define G_PP_TO_BOOL_43		1
#define G_PP_TO_BOOL_44		1
#define G_PP_TO_BOOL_45		1
#define G_PP_TO_BOOL_46		1
#define G_PP_TO_BOOL_47		1
#define G_PP_TO_BOOL_48		1
#define G_PP_TO_BOOL_49		1
#define G_PP_TO_BOOL_50		1
#define G_PP_TO_BOOL_51		1
#define G_PP_TO_BOOL_52		1
#define G_PP_TO_BOOL_53		1
#define G_PP_TO_BOOL_54		1
#define G_PP_TO_BOOL_55		1
#define G_PP_TO_BOOL_56		1
#define G_PP_TO_BOOL_57		1
#define G_PP_TO_BOOL_58		1
#define G_PP_TO_BOOL_59		1
#define G_PP_TO_BOOL_60		1
#define G_PP_TO_BOOL_61		1
#define G_PP_TO_BOOL_62		1
#define G_PP_TO_BOOL_63		1
#define G_PP_TO_BOOL_64		1
#define G_PP_TO_BOOL_65		1
#define G_PP_TO_BOOL_66		1
#define G_PP_TO_BOOL_67		1
#define G_PP_TO_BOOL_68		1
#define G_PP_TO_BOOL_69		1
#define G_PP_TO_BOOL_70		1
#define G_PP_TO_BOOL_71		1
#define G_PP_TO_BOOL_72		1
#define G_PP_TO_BOOL_73		1
#define G_PP_TO_BOOL_74		1
#define G_PP_TO_BOOL_75		1
#define G_PP_TO_BOOL_76		1
#define G_PP_TO_BOOL_77		1
#define G_PP_TO_BOOL_78		1
#define G_PP_TO_BOOL_79		1
#define G_PP_TO_BOOL_80		1
#define G_PP_TO_BOOL_81		1
#define G_PP_TO_BOOL_82		1
#define G_PP_TO_BOOL_83		1
#define G_PP_TO_BOOL_84		1
#define G_PP_TO_BOOL_85		1
#define G_PP_TO_BOOL_86		1
#define G_PP_TO_BOOL_87		1
#define G_PP_TO_BOOL_88		1
#define G_PP_TO_BOOL_89		1
#define G_PP_TO_BOOL_90		1
#define G_PP_TO_BOOL_91		1
#define G_PP_TO_BOOL_92		1
#define G_PP_TO_BOOL_93		1
#define G_PP_TO_BOOL_94		1
#define G_PP_TO_BOOL_95		1
#define G_PP_TO_BOOL_96		1
#define G_PP_TO_BOOL_97		1
#define G_PP_TO_BOOL_98		1
#define G_PP_TO_BOOL_99		1
#define G_PP_TO_BOOL_100	1
#define G_PP_TO_BOOL_101	1
#define G_PP_TO_BOOL_102	1
#define G_PP_TO_BOOL_103	1
#define G_PP_TO_BOOL_104	1
#define G_PP_TO_BOOL_105	1
#define G_PP_TO_BOOL_106	1
#define G_PP_TO_BOOL_107	1
#define G_PP_TO_BOOL_108	1
#define G_PP_TO_BOOL_109	1
#define G_PP_TO_BOOL_110	1
#define G_PP_TO_BOOL_111	1
#define G_PP_TO_BOOL_112	1
#define G_PP_TO_BOOL_113	1
#define G_PP_TO_BOOL_114	1
#define G_PP_TO_BOOL_115	1
#define G_PP_TO_BOOL_116	1
#define G_PP_TO_BOOL_117	1
#define G_PP_TO_BOOL_118	1
#define G_PP_TO_BOOL_119	1
#define G_PP_TO_BOOL_120	1
#define G_PP_TO_BOOL_121	1
#define G_PP_TO_BOOL_122	1
#define G_PP_TO_BOOL_123	1
#define G_PP_TO_BOOL_124	1
#define G_PP_TO_BOOL_125	1
#define G_PP_TO_BOOL_126	1
#define G_PP_TO_BOOL_127	1
#define G_PP_TO_BOOL_128	1
#define G_PP_TO_BOOL_129	1
#define G_PP_TO_BOOL_130	1
#define G_PP_TO_BOOL_131	1
#define G_PP_TO_BOOL_132	1
#define G_PP_TO_BOOL_133	1
#define G_PP_TO_BOOL_134	1
#define G_PP_TO_BOOL_135	1
#define G_PP_TO_BOOL_136	1
#define G_PP_TO_BOOL_137	1
#define G_PP_TO_BOOL_138	1
#define G_PP_TO_BOOL_139	1
#define G_PP_TO_BOOL_140	1
#define G_PP_TO_BOOL_141	1
#define G_PP_TO_BOOL_142	1
#define G_PP_TO_BOOL_143	1
#define G_PP_TO_BOOL_144	1
#define G_PP_TO_BOOL_145	1
#define G_PP_TO_BOOL_146	1
#define G_PP_TO_BOOL_147	1
#define G_PP_TO_BOOL_148	1
#define G_PP_TO_BOOL_149	1
#define G_PP_TO_BOOL_150	1
#define G_PP_TO_BOOL_151	1
#define G_PP_TO_BOOL_152	1
#define G_PP_TO_BOOL_153	1
#define G_PP_TO_BOOL_154	1
#define G_PP_TO_BOOL_155	1
#define G_PP_TO_BOOL_156	1
#define G_PP_TO_BOOL_157	1
#define G_PP_TO_BOOL_158	1
#define G_PP_TO_BOOL_159	1
#define G_PP_TO_BOOL_160	1
#define G_PP_TO_BOOL_161	1
#define G_PP_TO_BOOL_162	1
#define G_PP_TO_BOOL_163	1
#define G_PP_TO_BOOL_164	1
#define G_PP_TO_BOOL_165	1
#define G_PP_TO_BOOL_166	1
#define G_PP_TO_BOOL_167	1
#define G_PP_TO_BOOL_168	1
#define G_PP_TO_BOOL_169	1
#define G_PP_TO_BOOL_170	1
#define G_PP_TO_BOOL_171	1
#define G_PP_TO_BOOL_172	1
#define G_PP_TO_BOOL_173	1
#define G_PP_TO_BOOL_174	1
#define G_PP_TO_BOOL_175	1
#define G_PP_TO_BOOL_176	1
#define G_PP_TO_BOOL_177	1
#define G_PP_TO_BOOL_178	1
#define G_PP_TO_BOOL_179	1
#define G_PP_TO_BOOL_180	1
#define G_PP_TO_BOOL_181	1
#define G_PP_TO_BOOL_182	1
#define G_PP_TO_BOOL_183	1
#define G_PP_TO_BOOL_184	1
#define G_PP_TO_BOOL_185	1
#define G_PP_TO_BOOL_186	1
#define G_PP_TO_BOOL_187	1
#define G_PP_TO_BOOL_188	1
#define G_PP_TO_BOOL_189	1
#define G_PP_TO_BOOL_190	1
#define G_PP_TO_BOOL_191	1
#define G_PP_TO_BOOL_192	1
#define G_PP_TO_BOOL_193	1
#define G_PP_TO_BOOL_194	1
#define G_PP_TO_BOOL_195	1
#define G_PP_TO_BOOL_196	1
#define G_PP_TO_BOOL_197	1
#define G_PP_TO_BOOL_198	1
#define G_PP_TO_BOOL_199	1
#define G_PP_TO_BOOL_200	1
#define G_PP_TO_BOOL_201	1
#define G_PP_TO_BOOL_202	1
#define G_PP_TO_BOOL_203	1
#define G_PP_TO_BOOL_204	1
#define G_PP_TO_BOOL_205	1
#define G_PP_TO_BOOL_206	1
#define G_PP_TO_BOOL_207	1
#define G_PP_TO_BOOL_208	1
#define G_PP_TO_BOOL_209	1
#define G_PP_TO_BOOL_210	1
#define G_PP_TO_BOOL_211	1
#define G_PP_TO_BOOL_212	1
#define G_PP_TO_BOOL_213	1
#define G_PP_TO_BOOL_214	1
#define G_PP_TO_BOOL_215	1
#define G_PP_TO_BOOL_216	1
#define G_PP_TO_BOOL_217	1
#define G_PP_TO_BOOL_218	1
#define G_PP_TO_BOOL_219	1
#define G_PP_TO_BOOL_220	1
#define G_PP_TO_BOOL_221	1
#define G_PP_TO_BOOL_222	1
#define G_PP_TO_BOOL_223	1
#define G_PP_TO_BOOL_224	1
#define G_PP_TO_BOOL_225	1
#define G_PP_TO_BOOL_226	1
#define G_PP_TO_BOOL_227	1
#define G_PP_TO_BOOL_228	1
#define G_PP_TO_BOOL_229	1
#define G_PP_TO_BOOL_230	1
#define G_PP_TO_BOOL_231	1
#define G_PP_TO_BOOL_232	1
#define G_PP_TO_BOOL_233	1
#define G_PP_TO_BOOL_234	1
#define G_PP_TO_BOOL_235	1
#define G_PP_TO_BOOL_236	1
#define G_PP_TO_BOOL_237	1
#define G_PP_TO_BOOL_238	1
#define G_PP_TO_BOOL_239	1
#define G_PP_TO_BOOL_240	1
#define G_PP_TO_BOOL_241	1
#define G_PP_TO_BOOL_242	1
#define G_PP_TO_BOOL_243	1
#define G_PP_TO_BOOL_244	1
#define G_PP_TO_BOOL_245	1
#define G_PP_TO_BOOL_246	1
#define G_PP_TO_BOOL_247	1
#define G_PP_TO_BOOL_248	1
#define G_PP_TO_BOOL_249	1
#define G_PP_TO_BOOL_250	1
#define G_PP_TO_BOOL_251	1
#define G_PP_TO_BOOL_252	1
#define G_PP_TO_BOOL_253	1
#define G_PP_TO_BOOL_254	1
#define G_PP_TO_BOOL_255	1

// Description: Logical not operation definitions
// Notes:
// -----------------------------------------------------
#define G_PP_NOT(X)		G_PP_JOIN_DEF2(G_PP_NEGATE_, G_PP_TO_BOOL(X))

#define G_PP_NEGATE_0	1
#define G_PP_NEGATE_1	0


// Description: Logical And definitions
// Notes:
// -----------------------------------------------------
#define G_PP_AND(X, Y)	G_PP_JOIN_DEF3(G_PP_AND_, G_PP_TO_BOOL(X), G_PP_TO_BOOL(Y))

#define G_PP_AND_00		0
#define G_PP_AND_01		0
#define G_PP_AND_10		0
#define G_PP_AND_11		1

// Description: Logical Or definitions
// Notes:
// -----------------------------------------------------
#define G_PP_OR(X, Y)	G_PP_JOIN_DEF3(G_PP_OR_, G_PP_TO_BOOL(X), G_PP_TO_BOOL(Y))

#define G_PP_OR_00		0
#define G_PP_OR_01		1
#define G_PP_OR_10		1
#define G_PP_OR_11		1

// Description: Logical Xor definitions
// Notes:
// -----------------------------------------------------
#define G_PP_XOR(X, Y)	G_PP_JOIN_DEF3(G_PP_XOR_, G_PP_TO_BOOL(X), G_PP_TO_BOOL(Y))

#define G_PP_XOR_00		0
#define G_PP_XOR_01		1
#define G_PP_XOR_10		1
#define G_PP_XOR_11		0

// Description: Condition if definitions
// Notes:
// -----------------------------------------------------
#define G_PP_IF(COND, X)		G_PP_JOIN_DEF2(G_PP_IF_, G_PP_TO_BOOL(COND))(X)

#define G_PP_IF_0(X)			G_PP_EMPTY
#define G_PP_IF_1(X)			X

// Description: Condition if else definitions
// Notes:
// -----------------------------------------------------
#define G_PP_IF_ELSE(COND, X, Y)	G_PP_JOIN_DEF2(G_PP_IF_ELSE_, G_PP_TO_BOOL(COND))(X, Y)

#define G_PP_IF_ELSE_0(X, Y)		Y
#define G_PP_IF_ELSE_1(X, Y)		X

// Description: Conditional comma definition
// Notes:
// -----------------------------------------------------
#define G_PP_COMMA_IF(COND)		G_PP_JOIN_DEF2(G_PP_COMMA_IF_, G_PP_TO_BOOL(COND))

#define G_PP_COMMA_IF_0			G_PP_EMPTY
#define G_PP_COMMA_IF_1			,

#endif